/**
 * @author Xiao Xin
 * @description 
 * @version 1.0.0
 * @date 20210306
 * @copyright MIN-Group 国家重大科技基础设施——未来网络北大实验室：深圳市信息论与未来网络重点实验室
 */

 var SelfEncodingBase = require('../encoding/SelfEncodingBase').SelfEncodingBase
 var SignatureAlgorithm = require('../minsecurity/common').SignatureAlgorithm
 var ComponentType = require('../encoding/TLV').ComponentType
 var expectType = require('../encoding/TLV').expectType
 var readNonNegativeInteger = require('../encoding/TLV').readNonNegativeInteger
 var TlvComponentBase = require('./TlvComponentBase').TlvComponentBase
 var aggregation = require('../common/aggregation')//实现了多继承

 /**
  * @description 表示一个签名的类型
  * 1.格式如下：
  * SignatureType = SIGNATURE-TYPE-TYPE TLV-LENGTH <NonNegativeInteger>
  * 2.详情参见：http://gitea.qjm253.cn/PKUSZ-future-network-lab/minlib/src/branch/master/docs/PacketFormat.md#4-signature
  */ 
 class SignatureType extends aggregation(SelfEncodingBase,TlvComponentBase){
  constructor(){
    super()
    this.value = new Number()
  }

  /**
   * @description 根据一个签名类型值初始化一个 SignatureType
   * 1.值应该是已定义的
   * @param {SignatureTypeValue}
   */
  buildSignatureTypeByValue(signatureTypeValue){
    //检查签名类型值是否已知
    if(signatureTypeValue != SignatureAlgorithm.SM2WithSM3){
      var signatureTypeError = new SignatureTypeError()
      signatureTypeError.msg = 'Unknown signature type '+sigantureTpeValue
      throw signatureTypeError
    }
    this.value = signatureTypeValue
  }

  /**
   * @description 根据 TLV Block 初始化一个 SignatureType
   * @param {Block} block
   */
  buildSignatureTypeByBlock(block){
    try {
      this.wireDecode(block)
    } catch (error) {
      throw error
    }
  }

  /**
   * @description 获取签名类型值
   * @return {number}
   */
  getValue(){
    return this.value
  }

  /**
   * @description 将 SignatureType 线速编码为 TLV
   * @param {Encoder} Encoder
   * @return {number} totalLength
   */
  wireEncode(encoder){
		let totalLength = 0
		try {
			//编码 TLV-VALUE
			let tmpLen = encoder.prependNonNegativeInteger(BigInt(this.value))
			totalLength += tmpLen

			//编码 TLV-LENGTH
			tmpLen = encoder.prependVarNumber(BigInt(totalLength))
			totalLength += tmpLen

			//编码 TLV-TYPE
			tmpLen = encoder.prependVarNumber(ComponentType.TlvSignatureType)
			totalLength += tmpLen

			return totalLength
		} catch (error) {
			throw error
		}
	}

  /**
	 * @description 从 TLV Block 中解码出一个SignatureType
	 * @param {Block} block
	 */
	wireDecode(block){
    let result
		try {
			//检查Type是否正确
			expectType(block.getType(),ComponentType.TlvSignatureType)
      result = readNonNegativeInteger(block.getValue(),0,block.getLength())
      this.value = Number(result)
		} catch (error) {
			throw error
		}
	}
 

 }

 /**
  * @description 错误处理
  */
 class SignatureTypeError{
   constructor(){
     this.msg = ""
   }
   
   static error(){
    console.log('SignatureTypeError: '+this.msg)
   }
 }


 /**
  * @description 根据签名类型值创建一个 SignatureType
  * @param sigantureTpeValue
  * @return {SignatureType}
  */
 function createSignatureTypeByValue(signatureTypeValue){
  var signatureType = new SignatureType()
  try {
    signatureType.buildSignatureTypeByValue(signatureTypeValue)
    return signatureType
  } catch (error) {
    throw error 
  }
 }

 /**
  * @description 根据 TLV Block 创建一个 SignatureType
  * @param {Block} block
  * @return {SignatureType}
  */
 function createSignatureTypeByBlock(block){
   var signatureType =  new SignatureType()
   try {
     signatureType.buildSignatureTypeByBlock(block)
     return signatureType
   } catch (error) {
     throw error
   }
 }

 module.exports = {
   SignatureType: SignatureType,
   SignatureTypeError: SignatureTypeError,
   createSignatureTypeByValue: createSignatureTypeByValue,
   createSignatureTypeByBlock: createSignatureTypeByBlock
 }